package org.example.myleet.p385;

import java.util.ArrayList;
import java.util.Deque;
import java.util.LinkedList;
import java.util.List;

public class Solution {
    public NestedInteger deserialize(String s) {
        char[] sArr = s.toCharArray();
        StringBuilder sb = new StringBuilder();
        Deque<NestedInteger> stack = new LinkedList<>();
        NestedInteger root = new NestedInteger();
        NestedInteger cur = root;
        for (char c : sArr) {
            if (c == '[') {
                stack.push(cur);
                cur = new NestedInteger();
            } else if (c == ']') {
                if (sb.length() > 0) {
                    cur.add(new NestedInteger(simpleParseInt(sb)));
                    sb.delete(0, sb.length());
                }
                NestedInteger t = cur;
                cur = stack.pop();
                cur.add(t);
            } else if (Character.isDigit(c) || c == '-') {
                sb.append(c);
            } else if (c == ',') {
                if (sb.length() > 0) {
                    cur.add(new NestedInteger(simpleParseInt(sb)));
                    sb.delete(0, sb.length());
                }
            }
        }
        if (sb.length() > 0) {
            cur.add(new NestedInteger(Integer.parseInt(sb.toString())));
        }
        return root.getList().get(0);
    }

    private int simpleParseInt(StringBuilder sb) {
        boolean negative = false;
        if (sb.charAt(0) == '-') {
            negative = true;
        }
        int num = 0;
        for (int i = negative ? 1 : 0; i < sb.length(); ++i) {
            num = 10 * num + sb.charAt(i) - '0';
        }
        if (negative) {
            num *= -1;
        }
        return num;
    }

    public static class NestedInteger {

        private Integer value;

        private final List<NestedInteger> nested;

        // Constructor initializes an empty nested list.
        public NestedInteger() {
            this.nested = new ArrayList<>();
        }

        // Constructor initializes a single integer.
        public NestedInteger(int value) {
            this.value = value;
            this.nested = new ArrayList<>();
        }

        // @return true if this NestedInteger holds a single integer, rather than a nested list.
        public boolean isInteger() {
            return null != this.value;
        }

        // @return the single integer that this NestedInteger holds, if it holds a single integer
        // Return null if this NestedInteger holds a nested list
        public Integer getInteger() {
            return this.value;
        }

        // Set this NestedInteger to hold a single integer.
        public void setInteger(int value) {
            this.value = value;
        }

        // Set this NestedInteger to hold a nested list and adds a nested integer to it.
        public void add(NestedInteger ni) {
            this.nested.add(ni);
        }

        // @return the nested list that this NestedInteger holds, if it holds a nested list
        // Return empty list if this NestedInteger holds a single integer
        public List<NestedInteger> getList() {
            return this.nested;
        }

        @Override
        public String toString() {
            StringBuilder sb = new StringBuilder();
            if (this.isInteger()) {
                sb.append(this.value);
            } else {
                sb.append('[');
            }
            if (this.nested.size() > 0) {
                for (NestedInteger ni : nested) {
                    sb.append(ni.toString()).append(',');
                }
                sb.deleteCharAt(sb.length() - 1);
                sb.append(']');
            }
            return sb.toString();
        }
    }
}
